<?php

declare(strict_types=1);

/**
 * @Author:     Frank
 * @contact     frank_hhm@163.com
 * @Date:       2022-11-05 16:28:03
 * @Last Modified time: 2023-02-06 21:13:06
 */
namespace frank\base;

use frank\base\BaseModel;
use think\helper\Str;
use think\Model;

/**
 * Class BaseDao
 * @package app\dao
 */
abstract class BaseDao
{
    /**
     * 获取当前模型
     * @return string
     */
    abstract protected function setModel(): string;

    /**
     * 获取模型
     */
    protected function getModel()
    {
        return app()->make($this->setModel());
    }

    /**
     * 获取主键
     */
    protected function getPk()
    {
        return $this->getModel()->getPk();
    }
    
    /**
     * 获取表名称
     */
    protected function getTable()
    {
        return $this->getModel()->getTable();
    }

    public function model()
    {
        return $this->getModel();
    }

    /**
     * 获取搜索器和搜索条件key
     */
    private function getSearchData(array $withSearch)
    {
        $with = [];
        $whereKey = [];
        $respones = new \ReflectionClass($this->setModel());
        foreach ($withSearch as $fieldName) {
            $method = 'search' . Str::studly($fieldName) . 'Attr';
            if ($respones->hasMethod($method)) {
                $with[] = $fieldName;
            } else {
                $whereKey[] = $fieldName;
            }
        }
        return [$with, $whereKey];
    }

    /**
     * 根据搜索器获取搜索内容
     */
    protected function withSearchSelect(array $withSearch, ?array $data = [])
    {
        [$with] = $this->getSearchData($withSearch);
        return $this->getModel()->withSearch($with, $data);
    }

    /**
     * 搜索
     */
    public function search(array $where = [])
    {
        if ($where) {
            return $this->withSearchSelect(array_keys($where), $where);
        } else {
            return $this->getModel();
        }
    }
    
    /**
     * 获取某个字段数组
     */
    public function getColumn(array $where, string $field, string $key = '')
    {
        return $this->getModel()::where($where)->column($field, $key);
    }


    /**
     * 获取一条数据
     */
    public function get($id, ?array $field = [], ?array $with = [],$onlyTrashed = false)
    {
        if (is_array($id)) {
            $where = $id;
        } else {
            $where = [$this->getPk() => $id];
        }
        return $this->getModel()::where($where)->when(count($with), function ($query) use ($with) {
            $query->with($with);
        })->when($onlyTrashed, function ($query) {
            $query->onlyTrashed();
        })->field($field ?? ['*'])->find();
    }

    /**
     * 根据条件获取一条数据
     */
    public function getOne(array $where, ?string $field = '*', array $with = [])
    {
        $field = explode(',', $field);
        return $this->get($where, $field, $with);
    }

    /**
     * 获取某些条件数据
     */
    public function getPageList(array $where,$page = 0, $limit = 0,$order = ['id DESC'], $isArr = true, $field = '*')
    {
        $res = $this->getModel()->where($where)->field($field)->order($order)->page($page)->paginate($limit);
        if($isArr && $res) return $res->toArray();
        return $res;
    }

    /**
     * 获取某些条件数据
     */
    public function selectList(array $where, $page = 0, $limit = 0, $field = '*')
    {
        return $this->getModel()->where($where)->field($field)
            ->when($page && $limit, function ($query) use ($page, $limit) {
                $query->page($page, $limit);
            })->select();
    }


    /**
     * 数据详细
     */
    public function detail($filter){
        if(is_array($filter)){
           return $this->getModel()->where($filter)->find();
        }else{
            return $this->getModel()->find((int) $filter);
        }
    }

    /**
     * 软删除
     */
    public function destroy($ids,$isDes = false)
    {
        if (is_string($ids)) {
            $ids = explode(',',$ids);
        }
        return $this->getModel()::destroy($ids,$isDes);
    }


    /**
     * 读取数据条数
     */
    public function count(array $where = []): int
    {
        return $this->search($where)->count();
    }

    /**
     * 更新数据
     */
    public function update($id, array $data, ?string $key = null)
    {
        if (is_array($id)) {
            $where = $id;
        } else {
            $where = [is_null($key) ? $this->getPk() : $key => $id];
        }
        return $this->getModel()::update($data, $where);
    }

    /**
     * 插入数据
     */
    public function create(array $data)
    {
        return $this->getModel()::create($data);
    }

    /**
     * 插入数据
     */
    public function save(array $data)
    {
        return $this->getModel()->save($data);
    }

    /**
     * 插入数据
     */
    public function saveAll(array $data)
    {
        return $this->getModel()->saveAll($data);
    }


    /**
     * 删除
     */
    public function delete($id, ?string $key = null)
    {
        if (is_array($id)) {
            $where = $id;
        } else {
            $where = [is_null($key) ? $this->getPk() : $key => $id];
        }
        return $this->getModel()::where($where)->delete();
    }
}